package com.enfi.api.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author wind
 * @date 2020/3/12
 */
public class DateUtils {
	/**格式 yyyy-MM-dd HH:mm:ss**/
	public final static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
	/**格式 yyyy-MM-dd**/
	public final static String DATE_FORMAT_NOTIME = "yyyy-MM-dd";
	/**格式 yyyy-MM**/
	public final static String DATE_FORMAT_NODAY = "yyyy-MM";
	/**格式 HH:mm:ss**/
	public final static String DATE_FORMAT_NODATE = "HH:mm:ss";
	/**格式 MM-dd**/
	public final static String DATE_FORMAT_NOYEAR = "MM-dd";
	/**本周一**/
	public final static Integer WEEK_MONDDY = 0;//本周一
	/**本周二**/
	public final static Integer WEEK_TUESDAY = 1;//本周二
	/**本周三**/
	public final static Integer WEEK_WEDNESDAY = 2;//本周三
	/**本周四**/
	public final static Integer WEEK_THURSDAY = 3;//本周四
	/**本周五**/
	public final static Integer WEEK_FRIDAY = 4;//本周五
	/**本周六**/
	public final static Integer WEEK_SATURDAY = 5;//本周六
	/**本周日**/
	public final static Integer WEEK_SUNDAY = 6;//本周日
	/**上周一**/
	public final static Integer LAST_WEEK_MONDDY = -7;//上周一
	/**上周二**/
	public final static Integer LAST_WEEK_TUESDAY = -6;//上周二
	/**上周三**/
	public final static Integer LAST_WEEK_WEDNESDAY = -5;//上周三
	/**上周四**/
	public final static Integer LAST_WEEK_THURSDAY = -4;//上周四
	/**上周五**/
	public final static Integer LAST_WEEK_FRIDAY = -3;//上周五
	/**上周六**/
	public final static Integer LAST_WEEK_SATURDAY = -2;//上周六
	/**上周日**/
	public final static Integer LAST_WEEK_SUNDAY = -1;//上周日
	/**下周一**/
	public final static Integer NEXT_WEEK_MONDDY = 7;//下周一
	/**下周二**/
	public final static Integer NEXT_WEEK_TUESDAY = 1;//下周二
	/**下周三**/
	public final static Integer NEXT_WEEK_WEDNESDAY = 2;//下周三
	/**下周四**/
	public final static Integer NEXT_WEEK_THURSDAY = 3;//下周四
	/**下周五**/
	public final static Integer NEXT_WEEK_FRIDAY = 11;//下周五
	/**下周六**/
	public final static Integer NEXT_WEEK_SATURDAY = 12;//下周六
	/**下周日**/
	public final static Integer NEXT_WEEK_SUNDAY = 13;//下周日
	
	/**
	 * 格式化日期
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String getFormatTime(Date date, String pattern) {
		try {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
			return simpleDateFormat.format(date).toString();
		} catch (Exception e) {
			return "";
		}
	}
	public static String getFormatTime(String date, String pattern) {
		try {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
			return simpleDateFormat.format(getFormatDate(date,DATE_FORMAT_NOTIME)).toString();
		} catch (Exception e) {
			return "";
		}
	}
	public static Date getFormatDate(String date, String pattern) {
		try {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
			return simpleDateFormat.parse(date);
		} catch (Exception e) {
			return null;
		}
	}

	public static Date getFormatDate(String date) {
		try {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);
			return simpleDateFormat.parse(date);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 偏移时间（分钟）
	 * 
	 * @param date
	 *            时间
	 * @param offset
	 *            偏移量，负数代表往前，正数代表往后
	 * @return
	 */
	public static Date offSetMin(Date date, int offset) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MINUTE, offset);
		return cal.getTime();
	}

	/**
	 * 
	 * @param date
	 * @param field
	 * @param offset
	 * @return
	 */
	public static Date offSet(Date date, int field, int offset) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(field, offset);
		return cal.getTime();

	}

	public static String addSecond(Integer second) {
		Long currentTime = (long) (System.currentTimeMillis() + second * 1000);
		Date date = new Date(currentTime);
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String nowTime = df.format(date);

		return nowTime;
	}
	/**
	 * 加上天数
	 * @param date
	 * @param days
	 * @return
	 */
	public static String addDay(Date date,Integer days) {
		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		ca.add(Calendar.DATE,days);
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String nowTime = df.format(ca.getTime());
		return nowTime;
	}
	/**
	 * 加减月份
	 * @param date 当前时间
	 * @param count 加减数量 减少时传入负数
	 * @return
	 */
	public static String addMonth(Date date,Integer count) {
		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		ca.add(Calendar.MONTH,count);
		DateFormat df = new SimpleDateFormat("yyyy-MM");
		String nowTime = df.format(ca.getTime());
		return nowTime;
	}
	public static Long parseDateTomillion(Date date) {
		long millionSeconds = 0;
		try {
			String nowTime = getFormatTime(date, "yyyy-MM-dd HH:mm:ss");
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

			millionSeconds = format.parse(nowTime).getTime();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return millionSeconds;
	}
	/**
	 * 传入时间 返回星期几
	 * @param date
	 * @return
	 */
	public static Integer getEEEE(Date date){
		SimpleDateFormat format = new SimpleDateFormat("EEEE");
		String week = format.format(date);
		if("星期一".equalsIgnoreCase(week)){
			return 1;
		}else if("星期二".equalsIgnoreCase(week)){
			return 2;
		}else if("星期三".equalsIgnoreCase(week)){
			return 3;
		}else if("星期四".equalsIgnoreCase(week)){
			return 4;
		}else if("星期五".equalsIgnoreCase(week)){
			return 5;
		}else if("星期六".equalsIgnoreCase(week)){
			return 6;
		}else{
			return 7;
		}
	}
	/**
	 * 传入时间返回月份
	 * @param date
	 * @return
	 */
	public static String getMM(Date date){
		SimpleDateFormat format = new SimpleDateFormat("MM");
	    return format.format(date);
	}
	/**
	 * 获取今年年份
	 * @param date
	 * @return
	 */
	public static String getYear(Date date){
		SimpleDateFormat format = new SimpleDateFormat("yyyy");
	    return format.format(date);
	}
	/**
	 * 获取去年年份
	 * @param date
	 * @return
	 */
	public static String getLastYear(Date date){
		SimpleDateFormat format = new SimpleDateFormat("yyyy");
		String thisYear = format.format(date);
		Integer lastYear = Integer.parseInt(thisYear) - 1;
	    return String.valueOf(lastYear);
	}
	/**
	 * 获得当前日期与本周日相差的天数
	 * @param gmtCreate
	 * @return
	 */
	private static int getMondayPlus(Date date) {
		Calendar cd = Calendar.getInstance();
		cd.setTime(date);
		// 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
		int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; // 因为按中国礼拜一作为第一天所以这里减1
		if (dayOfWeek == 1) {
			return 0;
		} else {
			return 1 - dayOfWeek;
		}
	}
	/**
	 * 获得下周星期一或星期五日期
	 * @param gmtCreate
	 * @param nextWeek
	 * @return
	 */
	public static String getWeekDate(Date date,int nextWeek) {
		int mondayPlus = getMondayPlus(date);
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.add(GregorianCalendar.DATE, mondayPlus + nextWeek);
		Date monday = currentDate.getTime();
		return getFormatTime(monday, DATE_FORMAT_NOTIME);
	}
	/**
	 * 获取月末时间
	 * @param date
	 * @return
	 */
	public static String getMaxMonthDate(Date date){
		try {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
			return getFormatTime(calendar.getTime(),DATE_FORMAT_NOTIME);
		} catch (Exception e) {
			return "";
		}
	}
	/**
	 * 比较两个时间大小  格式 08:00:00
	 * @param t1 系统设置签到、签退时间
	 * @param t2 传入时间 当前签到、签退时间
	 * @return
	 */
	public static boolean largerTime(String t1,String t2){
        Date date1 ,date2;
        DateFormat formart = new SimpleDateFormat("hh:mm:ss");
        try{
            date1 = formart.parse(t1+":00");
            date2 = formart.parse(t2);
            if(date1.compareTo(date2) <= 0){
                return false;
            }else{
                return true;
            }
        }catch (ParseException e){
            System.out.println("date init fail!");
            e.printStackTrace();
            return false;
        }
    }
	/**
	 * 比较两个时间段分钟数
	 * @param t1 签到时间
	 * @param t2 签退时间
	 * @return
	 */
	public static Integer getMinutePoor(String t1, String  t2) {
		Date dt1 = getFormatDate(t1,DATE_FORMAT_NODATE);
		Date dt2 = getFormatDate(t2,DATE_FORMAT_NODATE);
	    long nd = 1000 * 24 * 60 * 60;
	    long nh = 1000 * 60 * 60;
	    long nm = 1000 * 60;
	    long diff = dt2.getTime() - dt1.getTime();
	    long hour = diff % nd / nh*60+diff % nd % nh / nm;
	    return Integer.parseInt(String.valueOf(hour));
	}
	/**
	 * 传入分钟返回小时 >=30分钟按一小时
	 * @param minute
	 * @return
	 */
	public static Integer getHour(Integer minute){
		Integer a = 60/2;//常量  基数
		Integer b = minute/60;//小时数
		Integer c = minute%60;//剩余分钟数
		if(c >= a){
			b = b+1;
		}
		return b;
	}
	/**
	 * 比较两个日期大小  当前时间小于等于比较时间返回true  大于返回false
	 * @param d1  当前时间
	 * @param d2  比较时间
	 * @return
	 */
	public static boolean compareDate(Date d1,Date d2){
        if (d1.getTime() <= d2.getTime()) {
            return true;
        } else if (d1.getTime() > d2.getTime()) {
            return false;
        }
        return false;
	}
	/**
	 * 传入日期返回当月一共有几周
	 * @param date
	 * @return
	 */
	public static int weekOfWeekCount(Date date){
		Calendar ca = Calendar.getInstance();  
		ca.setTime(date);  
	    ca.setFirstDayOfWeek(Calendar.MONDAY); 
		return ca.getActualMaximum(Calendar.WEEK_OF_MONTH);
	}
	/**
	 * 判断两个时间是否为同一个月份
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static boolean ifSameMonth(Date d1,Date d2){
		String m1 = getMM(d1);
		String m2 = getMM(d2);
		if(m1.equals(m2)){
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 比较两个时间相差天数
	 * @param d1 开始时间
	 * @param d2 结束时间
	 * @return
	 */
	public static long getDayPoor(String s1,String s2){
		Date d1 = getFormatDate(s1, DATE_FORMAT_NOTIME);
		Date d2 = getFormatDate(s2, DATE_FORMAT_NOTIME);
		Long a = d2.getTime() - d1.getTime();
		long b = a/1000/60/60/24;//天搜索
		return b;
	}
	/**
	 * 比较两个时间相差秒数
	 * @param s1 开始时间
	 * @param s2 结束时间
	 * @return 秒
	 */
	public static long getSecondPoor(String s1,String s2){
		Date d1 = getFormatDate(s1, DATE_FORMAT);
		Date d2 = getFormatDate(s2, DATE_FORMAT);
		Long a = d2.getTime() - d1.getTime();
		long b = a/1000;//秒
		return b;
	}
	/**
	 * 传入时间段 返回时间段内所有日期 
	 * @param d1 开始时间
	 * @param d2 结束时间
	 * @return List
	 */
	public static List<String> findDates(String s1, String s2){  
		Date d1 = getFormatDate(s1, DATE_FORMAT_NOTIME);
		Date d2 = getFormatDate(s2, DATE_FORMAT_NOTIME);
		List lDate = new ArrayList();  
		lDate.add(s1);  
		Calendar calBegin = Calendar.getInstance();

		// 使用给定的 Date 设置此 Calendar 的时间  
		calBegin.setTime(d1);  
		Calendar calEnd = Calendar.getInstance();  
		// 使用给定的 Date 设置此 Calendar 的时间  
		calEnd.setTime(d2);  
		// 测试此日期是否在指定日期之后  
		while (d2.after(calBegin.getTime())){  
		   // 根据日历的规则，为给定的日历字段添加或减去指定的时间量  
		   calBegin.add(Calendar.DAY_OF_MONTH, 1);  
		   lDate.add(getFormatTime(calBegin.getTime(),DATE_FORMAT_NOTIME));  
		}  
		return lDate;  
	}
	/**
     * 查询一周的开始时间和结束时间
     * @param date
     * @return
     */
    public static Map<String,String> onceWeek(String date){
    	Date d = getFormatDate(date, DATE_FORMAT_NOTIME);
        Calendar currentDate = new GregorianCalendar();
        currentDate.setTime(d);
        currentDate.setFirstDayOfWeek( Calendar.MONDAY);
        currentDate.set( Calendar.HOUR_OF_DAY, 0);
        currentDate.set( Calendar.MINUTE, 0);
        currentDate.set( Calendar.SECOND, 0);
        currentDate.set( Calendar.DAY_OF_WEEK,  Calendar.MONDAY);
        String dBegin = getFormatTime((Date) currentDate.getTime().clone(),DATE_FORMAT_NOTIME);
        currentDate.setFirstDayOfWeek( Calendar.MONDAY);
        currentDate.set( Calendar.HOUR_OF_DAY, 23);
        currentDate.set( Calendar.MINUTE, 59);
        currentDate.set( Calendar.SECOND, 59);
        currentDate.set( Calendar.DAY_OF_WEEK,  Calendar.SUNDAY);
        String dEnd = getFormatTime((Date) currentDate.getTime().clone(),DATE_FORMAT_NOTIME);
        //返回星期天和一个星期的日期和周几
        Map<String,String> map = new HashMap<>();
        map.put("dBegin",dBegin);
        map.put("dEnd",dEnd);
        return map;
    }
	/**
	 * 传入时间段 返回周集合
	 * @param s1 开始时间
	 * @param s2 结束时间
	 * @return List<Map<String,Object>>  dBegin开始时间  dEnd结束时间
	 */
	public static List<Map<String,Object>> findWeeks(List<Map<String,Object>> listMap,String s1, String s2){
		if(listMap == null){
			listMap = new ArrayList<Map<String, Object>>();
		}
		Map<String,String> be = onceWeek(s1);//获取第一周
		String dEnd = be.get("dEnd");//去周末
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("dBegin", s1);
		if(compareDate(getFormatDate(dEnd,DATE_FORMAT_NOTIME), getFormatDate(s2,DATE_FORMAT_NOTIME))){
			map.put("dEnd", dEnd);
			listMap.add(map);
			if(compareDate(getFormatDate(addDay(getFormatDate(dEnd,DATE_FORMAT_NOTIME), 1),DATE_FORMAT_NOTIME),getFormatDate(s2,DATE_FORMAT_NOTIME))){
				return findWeeks(listMap, addDay(getFormatDate(dEnd,DATE_FORMAT_NOTIME), 1), s2);
			}
		}else{
			map.put("dEnd", s2);
			listMap.add(map);
		}
		return listMap;
	}
	/**
	 * 传入时间段 返回月份集合
	 * @param s1 开始时间
	 * @param s2 结束时间
	 * @return List<Map<String,Object>>  dBegin开始时间  dEnd结束时间
	 */
	public static List<Map<String,Object>> findMonths(List<Map<String,Object>> listMap,String s1, String s2){
		if(listMap == null){
			listMap = new ArrayList<Map<String, Object>>();
		}
		String dEnd = getMaxMonthDate(getFormatDate(s1,DATE_FORMAT_NOTIME));//获取月末时间
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("dBegin", s1);
		if(compareDate(getFormatDate(dEnd,DATE_FORMAT_NOTIME), getFormatDate(s2,DATE_FORMAT_NOTIME))){
			map.put("dEnd", dEnd);
			listMap.add(map);
			if(compareDate(getFormatDate(addDay(getFormatDate(dEnd,DATE_FORMAT_NOTIME), 1),DATE_FORMAT_NOTIME),getFormatDate(s2,DATE_FORMAT_NOTIME))){
				return findMonths(listMap, addDay(getFormatDate(dEnd,DATE_FORMAT_NOTIME), 1), s2);
			}
		}else{
			map.put("dEnd", s2);
			listMap.add(map);
		}
		return listMap;
	}
	/**
	 * 传入月份 返回当月所有日期 
	 * @param date 月份 格式 2017-09
	 * @return List
	 */
	public static List<String> findDates(String date){  
		String s1 = date+"-01";
		String s2 = getMaxMonthDate(getFormatDate(s1,DATE_FORMAT_NOTIME));
		Date d1 = getFormatDate(s1, DATE_FORMAT_NOTIME);
		Date d2 = getFormatDate(s2, DATE_FORMAT_NOTIME);
		List lDate = new ArrayList();  
		lDate.add(s1);  
		Calendar calBegin = Calendar.getInstance();  
		// 使用给定的 Date 设置此 Calendar 的时间  
		calBegin.setTime(d1);  
		Calendar calEnd = Calendar.getInstance();  
		// 使用给定的 Date 设置此 Calendar 的时间  
		calEnd.setTime(d2);  
		// 测试此日期是否在指定日期之后  
		while (d2.after(calBegin.getTime())){  
		   // 根据日历的规则，为给定的日历字段添加或减去指定的时间量  
		   calBegin.add(Calendar.DAY_OF_MONTH, 1);  
		   lDate.add(getFormatTime(calBegin.getTime(),DATE_FORMAT_NOTIME));  
		}  
		return lDate;  
	}
	/**
	 * 传入年份 返回所有月份
	 * @param year年份
	 * @return List<String>
	 */
	public static List<String> monthList(String year){
		List<String> monthList = new ArrayList<String>();
		monthList.add(year+"-01");
		monthList.add(year+"-02");
		monthList.add(year+"-03");
		monthList.add(year+"-04");
		monthList.add(year+"-05");
		monthList.add(year+"-06");
		monthList.add(year+"-07");
		monthList.add(year+"-08");
		monthList.add(year+"-09");
		monthList.add(year+"-10");
		monthList.add(year+"-11");
		monthList.add(year+"-12");
		return monthList;
	}

	/**
	 * 获取两个日期之间的所有月份
	 * @param starttime 开始时间
	 * @param endtime 结束时间
	 * @return
	 */
	public static List<String> findMonths(String starttime,String endtime){
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月
			Calendar min = Calendar.getInstance();
			Calendar max = Calendar.getInstance();
			min.setTime(sdf.parse(starttime));
			min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
			max.setTime(sdf.parse(endtime));
			max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
			Calendar curr = min;
			List<String> result =new ArrayList<>();
			while (curr.before(max)) {
				result.add(sdf.format(curr.getTime()));
				curr.add(Calendar.MONTH, 1);
			}
			return result;
		} catch (Exception e) {
				e.printStackTrace();
				return null;
		}
	}
	public static void main(String[] args) throws ParseException {
		String data = "2017-10-1";
		System.err.println(getSecondPoor("2017-12-13 14:15:30", "2017-12-13 14:15:58"));
	}
}
